-module(packetgenerator_exp).
-export([init/7]).
-include_lib("records.hrl").

%MeanLength : The mean of packet length
%Rate: The rate of the generator for each unit time
%Sources: The sources path for the packet
%InputPid: The first Input Process Id
init(Main, N, MeanLength, Rate, Sources, InputPid, Utils) ->
  Data = generate_random(N, MeanLength),
  {HT,Times} = get_times(generate_random(N, 1/Rate)),
  Main ! {self(), {max, HT}},
  %io:format("Times:~p~n",[lists:reverse(Times)]),
  run(Data, Times, InputPid, Sources, Utils).

get_times(Times)->
  NTimes = get_times(Times, [0]),
  [HT|_] = NTimes,
  [_|T]=lists:reverse(NTimes),
  {HT,T}.

get_times([], NewTimes) ->
  NewTimes;

get_times([HO|TO], NewTimes) ->
  [HN|_]  = NewTimes,
  get_times(TO, [(HN+HO)|NewTimes]).

run([], Times, Pid, Sources, Utils) ->
  receive
    {_, {time_change, _}} ->
      run([], Times, Pid, Sources, Utils);
    {From, finish} ->
      From ! ok,
      run([], Times, Pid, Sources, Utils);
    {From, close}  ->
      From ! close
  end;

run(Data, Times, Pid, Sources, Utils) ->
  receive
    {_, {time_change, NowTime}} ->
      { NewData,NewTimes } = tranfer(Data, Times, Pid, Sources, Utils, NowTime),
      run(NewData, NewTimes, Pid, Sources, Utils);
    {From, finish} ->
      From ! ok,
      run(Data, Times, Pid, Sources, Utils)
  end.

tranfer([], [], _, _, _, _)->
  {[],[]};

tranfer([HD|TD], [HT|TT], Pid, Sources, Utils, NowTime)->
  if
    HT > NowTime ->
      {[HD|TD],[HT|TT]};
    true ->
      Id = utils:get_id(Utils),
      P = #packet{id=Id, sources=Sources, plength=HD},
      Pid ! {self(), {packet, P}},
      receive
        {_, rec_ok} ->
          ok
      end,
      tranfer(TD, TT, Pid, Sources, Utils, NowTime)
  end.

generate_random(N, Mean) ->
  utils:reset_random(),
  generate_random(N, [] , Mean).

generate_random(N, T, Mean) ->
  if
    N>0 ->
      Data = utils:exp_random(Mean),
      generate_random(N-1, [Data|T], Mean);
    true ->
      T
  end.
